package com.bridgeintelligent.tag.engine.es.query.condition;

import com.bridgeintelligent.tag.engine.api.EngineException;
import com.bridgeintelligent.tag.engine.api.Filter;
import com.wayneleo.quickstart.framework.ExceptionCode;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

/**
 * Created by JackCheung on 2019/10/15 6:51 AM.
 */
public class ConditionHelper {

    /**
     * 等于
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder termQuery(Filter filter) {
        QueryBuilder queryBuilder;
        if (filter.getValueList()
                  .size() > 1) {
            queryBuilder = QueryBuilders.termsQuery(fetchIdInDate(filter), filter.getValueList());
        } else {//过滤条件size等于1时
            queryBuilder = QueryBuilders.termQuery(fetchIdInDate(filter), filter.getValueList()
                                                                                .get(0));
        }
        return queryBuilder;
    }

    /**
     * 模糊包含或者模糊不包含检查格式
     *
     * @param filter 过滤条件
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static void checkFormat(Filter filter) {
        if (filter.getValueList()
                  .size() > 1) {
            throw new EngineException(new ExceptionCode(999, "模糊包含或者不包含只能传一个元素！"));
        }
    }

    /**
     * 大于
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder gtQuery(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gt(filter.getValueList()
                                      .get(0));
    }

    /**
     * 大于(日期)
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder gtQueryDate(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gt(filter.getValueList()
                                      .get(0));
    }

    /**
     * 小于
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder ltQuery(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .lt(filter.getValueList()
                                      .get(0));
    }

    /**
     * 小于(日期)
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder ltQueryDate(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .lt(filter.getValueList()
                                      .get(0));
    }

    /**
     * 大于等于
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder gteQuery(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gte(filter.getValueList()
                                       .get(0));
    }

    /**
     * 大于等于(日期)
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder gteQueryDate(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gte(filter.getValueList()
                                       .get(0));
    }

    /**
     * 小于等于
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder lteQuery(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .lte(filter.getValueList()
                                       .get(0));
    }

    /**
     * 小于等于(日期)
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder lteQueryDate(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .lte(filter.getValueList()
                                       .get(0));
    }

    /**
     * 在...之中
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder amongQuery(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gte(filter.getValueList()
                                       .get(0))
                            .lte(filter.getValueList()
                                       .get(1));
    }

    /**
     * 在...之中(日期)
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder amongQueryDate(Filter filter) {
        return QueryBuilders.rangeQuery(fetchIdInDate(filter))
                            .gte(filter.getValueList()
                                       .get(0))
                            .lt(filter.getValueList()
                                       .get(1));
    }

    /**
     * 模糊包含
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder containVagueQuery(Filter filter) {
        return QueryBuilders.wildcardQuery(fetchIdInDate(filter), "*" + filter.getValueList()
                                                                              .get(0) + "*");
    }

    /**
     * 不存在（字符型）
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder notExistQuery(Filter filter) {
        return QueryBuilders.boolQuery()
                            .should(QueryBuilders.boolQuery()
                                                 .mustNot(QueryBuilders.existsQuery(fetchIdInDate(filter))));
    }

    /**
     * 不存在（数值型）
     *
     * @param filter 过滤条件
     * @return QueryBuilder
     */
    public static QueryBuilder notExistNumQuery(Filter filter) {
        return QueryBuilders.boolQuery()
                            .should(QueryBuilders.boolQuery()
                                                 .mustNot(QueryBuilders.existsQuery(fetchIdInDate(filter))));
    }

    public static void checkFormatString(Filter filter) {
        try {
            if (filter.getValueList()
                      .size() != 2) {
                throw new EngineException(new ExceptionCode(999, "逻辑计算值格式不正确！"));
            }
        } catch (Exception e) {
            throw new EngineException(new ExceptionCode(999, "逻辑计算值格式不正确！"));
        }
    }

    private static String fetchIdInDate(Filter filter) {
        return DateBuilder.handler(filter);
    }
}
